package com.tin.triper.Background;

import java.util.Date;

import com.tin.triper.Constants;
import com.tin.triper.R;
import com.tin.triper.Data.LocationProvider;
import com.tin.triper.UI.RecordActivity;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.RemoteViews;

public class RecorderService extends Service {

	private final IBinder binder = new RecordBinder();
	private LocationManager locationManager;
	private LocationListener listener;
	int tripId;
	int lastLocationId;
	final int updateTime = 54;
	final int updateDistance = 500;
	SharedPreferences prefs;
	NotificationManager notificationManager;

	public class RecordBinder extends Binder {
		public RecorderService getService() {
			return RecorderService.this;
		}
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return START_STICKY;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		prefs = getSharedPreferences(Constants.PREFS_NAME, MODE_PRIVATE);
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		startRecording();
		return binder;
	}

	public void startRecording() {
		if (prefs.getInt(Constants.BATTERY_LEVEL, 100) > 20)
			if (prefs.getBoolean(Constants.IS_RECORDING, false)) {
				listener = new RecorderListener();
				locationManager.requestLocationUpdates(
						LocationManager.GPS_PROVIDER, prefs.getInt(
								Constants.GPS_TIME_UPDATE, updateTime)*1000, prefs
								.getInt(Constants.GPS_DISTANCE_UPDATE,
										updateDistance), listener);
				setupNotification();
				updateWidgetStartRecording();
			}
	}

	public void updateLocation() {
		if (listener != null)
			locationManager.removeUpdates(listener);
		else
			listener = new RecorderListener();
		if (prefs.getInt(Constants.BATTERY_LEVEL, 100) > 20)
			locationManager
					.requestLocationUpdates(LocationManager.GPS_PROVIDER, prefs
							.getInt(Constants.GPS_TIME_UPDATE, updateTime)*1000,
							prefs.getInt(Constants.GPS_DISTANCE_UPDATE,
									updateDistance), listener);

	}

	public void stopRecording() {
		if (prefs.getBoolean(Constants.IS_RECORDING, false)) {
			locationManager.removeUpdates(listener);
			cancelNotification();
			updateWidgetStopRecording();
		}
	}

	private void updateWidgetStartRecording() {
		RemoteViews remoteViews = new RemoteViews(getPackageName(),
				R.layout.widget_recroder);

		Intent addStartTriperIntent = new Intent(this, RecorderWidget.class);
		addStartTriperIntent.setAction(RecorderWidget.ACTION_WIDGET_TRIPER);

		PendingIntent addStartTriperPendingIntent = PendingIntent.getBroadcast(
				this, 0, addStartTriperIntent, 0);

		remoteViews.setOnClickPendingIntent(
				R.id.widget_recorder_button_trip, addStartTriperPendingIntent);
		
		Intent addTextIntent = new Intent(this, RecorderWidget.class);
		addTextIntent.setAction(RecorderWidget.ACTION_WIDGET_ADD_TEXT);

		PendingIntent addTextPendingIntent = PendingIntent.getBroadcast(this,
				0, addTextIntent, 0);

		remoteViews.setOnClickPendingIntent(R.id.widget_recorder_button_text,
				addTextPendingIntent);

		Intent addVoiceIntent = new Intent(this, RecorderWidget.class);
		addVoiceIntent.setAction(RecorderWidget.ACTION_WIDGET_ADD_VOICE);

		PendingIntent addVoicePendingIntent = PendingIntent.getBroadcast(this,
				0, addVoiceIntent, 0);

		remoteViews.setOnClickPendingIntent(R.id.widget_recorder_button_voice,
				addVoicePendingIntent);

		Intent addPhotoIntent = new Intent(this, RecorderWidget.class);
		addPhotoIntent.setAction(RecorderWidget.ACTION_WIDGET_ADD_PHOTO);

		PendingIntent addPhotoPendingIntent = PendingIntent.getBroadcast(this,
				0, addPhotoIntent, 0);

		remoteViews.setOnClickPendingIntent(R.id.widget_recorder_button_photo,
				addPhotoPendingIntent);

		Intent addVideoIntent = new Intent(this, RecorderWidget.class);
		addVideoIntent.setAction(RecorderWidget.ACTION_WIDGET_ADD_VIDEO);

		PendingIntent addVideoPendingIntent = PendingIntent.getBroadcast(this,
				0, addVideoIntent, 0);

		remoteViews.setOnClickPendingIntent(R.id.widget_recorder_button_video,
				addVideoPendingIntent);

		remoteViews.setViewVisibility(R.id.widget_recorder_button_video,
				View.VISIBLE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_text,
				View.VISIBLE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_voice,
				View.VISIBLE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_photo,
				View.VISIBLE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_start,
				View.GONE);

		ComponentName thisWidget = new ComponentName(this, RecorderWidget.class);
		AppWidgetManager.getInstance(this).updateAppWidget(thisWidget,
				remoteViews);
	}

	private void updateWidgetStopRecording() {
		RemoteViews remoteViews = new RemoteViews(getPackageName(),
				R.layout.widget_recroder);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_video,
				View.GONE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_text,
				View.GONE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_voice,
				View.GONE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_photo,
				View.GONE);
		remoteViews.setViewVisibility(R.id.widget_recorder_button_start,
				View.VISIBLE);
		
		Intent addStartTriperIntent = new Intent(this, RecorderWidget.class);
		addStartTriperIntent.setAction(RecorderWidget.ACTION_WIDGET_TRIPER);

		PendingIntent addStartTriperPendingIntent = PendingIntent.getBroadcast(
				this, 0, addStartTriperIntent, 0);

		remoteViews.setOnClickPendingIntent(
				R.id.widget_recorder_button_trip, addStartTriperPendingIntent);
		
		Intent startTripIntent = new Intent(this, RecorderWidget.class);
		startTripIntent.setAction(RecorderWidget.ACTION_WIDGET_START_TRIP);

		PendingIntent startTripPendingIntent = PendingIntent.getBroadcast(this,
				0, startTripIntent, 0);

		remoteViews.setOnClickPendingIntent(R.id.widget_recorder_button_start,
				startTripPendingIntent);

		ComponentName thisWidget = new ComponentName(this, RecorderWidget.class);
		AppWidgetManager.getInstance(this).updateAppWidget(thisWidget,
				remoteViews);
	}

	private void setupNotification() {
		int icon=0;
		if(Build.VERSION.SDK_INT>8)
			icon= R.drawable.tray_icon; 
		else
			icon= R.drawable.rec; 
		CharSequence tickerText = getString(R.string.notification_message_ticker); // ticker-text
		long when = System.currentTimeMillis(); // notification time
		Context context = getApplicationContext(); // application Context
		CharSequence contentTitle = getString(R.string.notification_message_title); // message
																					// title
		CharSequence contentText = getString(R.string.notification_message_text); // message
																					// text

		Intent notificationIntent = new Intent(this, RecordActivity.class);
		notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_SINGLE_TOP
				| Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
		notificationIntent.putExtra(Constants.ACTIVITY_MODE, -1);
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				notificationIntent, 0);

		// the next two lines initialize the Notification, using the
		// configurations above
		Notification notification = new Notification(icon, tickerText, when);
		notification.flags |= Notification.FLAG_ONGOING_EVENT
				| Notification.FLAG_NO_CLEAR;
		notification.setLatestEventInfo(context, contentTitle, contentText,
				contentIntent);
		notificationManager.notify(999, notification);
	}

	private void cancelNotification() {
		try {
			notificationManager.cancel(999);
		} catch (Exception e) {
		}
	}

	private class RecorderListener implements LocationListener {
		@Override
		public void onLocationChanged(Location loc) {
			if (new Date().getTime()
					- prefs.getLong(Constants.LAST_INSERTED_LOCATION_TIME, 0) < 10000)
				return;
			prefs.edit()
					.putLong(Constants.LAST_INSERTED_LOCATION_TIME,
							new Date().getTime()).commit();
			IntentFilter batteryLevelFilter = new IntentFilter(
					Intent.ACTION_BATTERY_CHANGED);
			registerReceiver(new BatteryReviever(), batteryLevelFilter);
			long time;
			if (loc != null)
				if (prefs.getInt(Constants.RECORDED_TRIP_ID, 0) != 0) {
					long timeToAdd = 0;
					float distanceToAdd = 0;
					time = new Date().getTime();
					ContentValues values = new ContentValues();
					values.put(LocationProvider.LOCATION_LATITUDE,
							loc.getLatitude());
					values.put(LocationProvider.LOCATION_TIME, time);
					values.put(LocationProvider.LOCATION_LONGITUDE,
							loc.getLongitude());
					values.put(LocationProvider.TRIP_ID,
							prefs.getInt(Constants.RECORDED_TRIP_ID, 0));
					getContentResolver().insert(
							LocationProvider.CONTENT_URI_LOCATION, values);

					if (prefs.getInt(Constants.LAST_INSERTED_LOCATION_ID, 0) != 0) {
						Location previousLocation = null;
						Cursor cursor = getContentResolver()
								.query(LocationProvider.CONTENT_URI_LOCATION,
										new String[] {
												LocationProvider.LOCATION_ALTITUDE,
												LocationProvider.LOCATION_LATITUDE,
												LocationProvider.LOCATION_LONGITUDE,
												LocationProvider.LOCATION_TIME },
										LocationProvider.LOCATION_ID
												+ " ='"
												+ prefs.getInt(
														Constants.LAST_INSERTED_LOCATION_ID,
														0) + "'", null, null);
						if (cursor.moveToFirst()) {
							previousLocation = new Location("none");
							previousLocation.setLongitude(cursor.getDouble(2));
							previousLocation.setLatitude(cursor.getDouble(1));
							previousLocation.setTime(cursor.getLong(3));
							timeToAdd = cursor.getLong(3);
						}
						cursor.close();
						if (previousLocation != null) {
							Date date = new Date();
							timeToAdd = date.getTime() - timeToAdd;
							distanceToAdd = loc.distanceTo(previousLocation);
						}
						cursor = getContentResolver().query(
								LocationProvider.CONTENT_URI_TRIPS,
								new String[] { LocationProvider.TRIP_TIME,
										LocationProvider.TRIP_LENGTH },
								LocationProvider.TRIP_ID
										+ " ='"
										+ prefs.getInt(
												Constants.RECORDED_TRIP_ID, 0)
										+ "'", null, null);
						if (cursor != null)
							if (cursor.moveToFirst()) {
								timeToAdd += cursor.getLong(0);
								distanceToAdd += cursor.getFloat(1);
							}
						cursor.close();
						if (timeToAdd > 0 && distanceToAdd > 0) {
							values = null;
							values = new ContentValues();
							values.put(LocationProvider.TRIP_TIME, timeToAdd);
							values.put(LocationProvider.TRIP_LENGTH,
									distanceToAdd);
							values.put(LocationProvider.TRIP_ID,
									prefs.getInt(Constants.RECORDED_TRIP_ID, 0));
							getContentResolver().update(
									LocationProvider.CONTENT_URI_TRIPS,
									values,
									LocationProvider.TRIP_ID
											+ " ='"
											+ prefs.getInt(
													Constants.RECORDED_TRIP_ID,
													0) + "'", null);
						}
					}
					Cursor lastLocationCursor = getContentResolver()
							.query(LocationProvider.CONTENT_URI_LOCATION,
									new String[] { LocationProvider.LOCATION_ID },
									LocationProvider.LOCATION_TIME + " ='"
											+ time + "'", null, null);
					if (lastLocationCursor.moveToFirst())
						prefs.edit()
								.putInt(Constants.LAST_INSERTED_LOCATION_ID,
										lastLocationCursor.getInt(0)).commit();
					lastLocationCursor.close();

				}
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub

		}
	}

	private class BatteryReviever extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			try {
				context.unregisterReceiver(this);
			} catch (Exception e) {
			}
			int rawlevel = intent.getIntExtra("level", -1);
			int scale = intent.getIntExtra("scale", -1);
			int level = -1;
			if (rawlevel >= 0 && scale > 0) {
				level = (rawlevel * 100) / scale;
			}
			prefs.edit().putInt(Constants.BATTERY_LEVEL, level).commit();
			if (level < 20) {
				stopRecording();
			}

		}

	}
}
